Module# 02: Generic
Programming Lecture#05: Bounded
Argument Generic Classes
// Example 5.1: Why bounding of
types in generic class definition?
GenericError<T> {
T[ ] array; // An array of type T
// Pass the constructor a reference to an array of type T.
GenericError (T[ ] t) {
array = t;
}
double average() { // Return type double in all cases
double sum = 0.0;
for(int i=0; i < array.length; i++)
sum += array[i].doubleValue(); // Here is compiler error!
return sum / array.length;
}
}
// Example 5.2 : Upper bound of
argument in generic class definition
GenericBound<T extends Number > {
T[ ] array; // an array of type T
// Pass the constructor a reference to an array of type T.
GenericBound (T[ ] t) {
array = t;
}
double average() { // Return type double in all cases
double sum = 0.0;
for(int i=0; i < array.length; i++)
sum += array[i].doubleValue(); // Now, it is okay
return sum / array.length;
}
}
class GenericBoundDemo {
public static void main(String args[]) {
Integer intArray[] = { 1, 2, 3, 4, 5 };
GenericBound <Integer> intData = new GenericBound
<Integer>(intArray);
double avgInt = intData.average();
System.out.println("Average is " + avgInt);
Double doubleArray[] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
GenericBound <Double> doubleData = new GenericBound
<Double>(doubleArray);
double abgDouble = doubleData.average();
System.out.println("Average is " + avgDouble);
String strArray[] = { "1", "2", "3", "4", "5" };
GenericBound <String> strData = new GenericBound
<String>(strArray);
/*
double avgStr =
strData.average(); // ERROR!
System.out.println("Average
is " + avgStr); */
}
}
// Example 5.3: Generic class with
another limitation
class Student<T extends Number>{
String name;
T [ ] marks; // To store the marks obtained by
a student
// The usual constructor for the
generic class Student
Student (T [ ] m) {
marks = m;
}
//
This method to calculate the total of marks obtained by a student
double total( ) {
double sum = 0.0;
for(int i = 0; i < marks.length; i++)
sum += marks[i].doubleValue();
return (sum);
}
// This method compares the marks
obtained by this
// student with another student
boolean compareMarks(Student<T> others) {
if ( total() == others.total() )
return true;
return false;
}
} // End of the generic class definition
// Driver class while
instantiating the Student generic class with different number format.
class GenericLimitationDemo {
public static void main(String args[]) {
Integer intMarks1[] = { 44, 55, 33, 66, 77 }; // Marks stored in integer for s1
Student<Integer> s1IntMarks = new Student<Integer>(intMarks1);
System.out.println("Total marks " + s1IntMarks.total());
Integer intMarks2[] = { 49, 39, 53, 69 }; // Marks stored in integer for s2
Student<Integer> s2IntMarks = new Student<Integer>(intMarks2);
System.out.println("Total marks " + s2IntMarks.total());
// Compare marks between s1 and s2
if (s1IntMarks.compareMarks (s2IntMarks))
System.out.println("Same marks");
else
System.out.println("Different marks.");
Double doubleMarks[] = { 43.5, 55.5, 32.5, 66.5, 77.0 }; // Marks stored in double for s3
Student<Double> s3DoubleMarks = new Student<Double>(doubleMarks);
System.out.println("Total marks " + s3DoubleMarks.total());
Float floatMarks[] = { 50.0F, 40.0F, 60.0F, 65.0F }; // Marks stored in float for s4
Student<Float> s4FloatMarks = new Student<Float>(floatMarks);
System.out.println("Total marks " + s4FloatMarks.total());
// Compare marks between s2 and s3
if (s2IntMarks.compareMarks (s3DoubleMarks)) // ERROR!
System.out.println("Same marks");
else
System.out.println("Different marks.");
// Compare marks between s3 and s4
if (s3DoubleMarks.compareMarks (s4FloatMarks))
//
ERROR!
System.out.println("Same marks");
else
System.out.println("Different marks.");
}
}
// Example 5.4: Generic class with
wildcard argument
class Student <T extends Number>{
String name;
T [ ] marks; // To store the marks obtained by
a student
// The usual constructor for the
generic class Student
Student (T [ ] m) {
marks = m;
}
//
This method to calculate the total of marks obtained by a student
double total( ) {
double sum = 0.0;
for(int i = 0; i < marks.length; i++)
sum += marks[i].doubleValue();
return (sum);
}
// This method compares the marks
obtained by this
// student with another student
boolean compareMarks(Student<?>
others) {
if ( total() == others.total() )
return true;
return false;
}
} // End of the generic class definition
// Example 5.5: Definition of all
the classes in of animals
class Animal {
long lifespan;
float weigh;
Animal(long years, float kg) {
lifespan = years;
weight = kg;
}
public void print( ) {
System.out.println(“Maximum longevity: “ + lifespan + “
in years”);
System.out.println(“Maximum weight: “ + weight + “
in kgs”);
}
}
//
End of class Animal
class Aquatic extends Animal {
boolean scale; // true: has scale, false: no
scale
Aquatic(long years, float kg, boolean skin) {
super(years, kgs); // Super class constructor
scale = skin;
}
public void print( ) {
super.print();
//
Call the super class method
System.out.println(“Has scale?
“ + scale);
}
}
//
End of class Aquatic
class Land extends Animal {
short vision;
//0 =
nocturnal, 1 = only day light, 2 = both
Land(long years, float kg, short vision) {
super(years, kgs); // Super class constructor
this.vision = vision;
}
}
//
End of class Land
class Pet extends Land {
String name;
Pet(long
years, float kg, short vision, String name) {
super(years, kgs, vision, name);
//
Super class constructor
this.name = name;
}
}
//
End of class Pet
class Wild extends Land {
float speed;
//
Maximum running speed in mph
Wild(long years, float kg, short vision, float speed) {
super(years, kgs, vision, name);
//
Super class constructor
this.speed = speed;
}
}
//
End of class Wild
// Defining a generic class to
maintain list of all animals
class AnimalWorld<T extends Animal> {
//Type parameter is limited to Animal and its sub
classes
T [ ] listOfAnimals;
AnimalWorld(T [ ] list) // Generic constructor to create a list of type
T
listOfAnimals = list;
}
}
//
End of the generic class AnimalWorld
// Defining different methods with
different bounds of arguments
class BoundedWildcards {
//Case 1: Unbound wildcard: Any
object can be passed as its argument.
static void vitality(AnimalWorld<?> animals) {
//To print the vitality of animals in the list of
animals
for(Animal a : animals)
a.print();
System.out.println();
}
// Case 2: Lower bounded wildcard:
Any object of Aquatic or Animal can // be passed as its argument.
static void showSea(AnimalWorld<?
super Aquatic> animals) {
//For aquatic or unknown animals
for(Object obj : animals)
obj.print();
// Call the method defined in
Animal/ Aquatic class
System.out.println();
}
// Case 3a: Upper bounded
wildcard: Any object of Land/ Pet/ Wild can // be passed as its argument.
static void showLand(AnimalWorld<?
extends Land> animals) {
//For Land or any of its subclasses
for(int i = 0; i < animals.listOfAnimals.length)
{
animals.listOfAnimals[i].print();
// Call the method defined in Animal class
System.out.println(“Vision : “ +
animals.listOfAnimals[i].vision);
}
System.out.println();
}
// Case 3b: Upper bounded
wildcard: Any object of only Pet class
can // be passed as its argument.
static void showPet(AnimalWorld<?
extends Pet> animals) {
//For lists of Pet objects only
for(int i = 0; i < animals.listOfAnimals.length)
{
System.out.println(“Pet’s name: “ +
animals.listOfAnimals[i].name);
animals.listOfAnimals[i].print();
// Call the method defined in Animal class
System.out.println(“Vision : “ +
animals.listOfAnimals[i].vision);
}
System.out.println();
}
// Case 3c: Upper bounded
wildcard: Any object of only Wild class
can // be passed as its argument.
static void showWild(AnimalWorld<?
extends Wild> animals) {
//For objects of Wild class only
for(int i = 0; i < animals.listOfAnimals.length)
{
animals.listOfAnimals[i].print();
// Call the method defined in
Animal class
System.out.println(“Maximum running speed: “ +
animals.listOfAnimals[i].speed + “ in mph”);
System.out.println(“Vision : “ +
animals.listOfAnimals[i].vision);
}
System.out.println();
}
}
//
End of the method definitions in class BoundedWildcards
class BoundedWildcardArgumentsDemo {
public static void main(String args[]) {
// Create a list of unknown animals of class Animal
Animal unknown = new Animal(40, 720);
// An unknown animal object is
created
Animal u [] = {unknown}; // Array of unknown animals
AnimalWorld<Animal> uList = new AnimalWorld<Animal>(u);
// Place the unknown into a list
// Create a list of aquatic animals
Aquatic whale = new Aquatic(90, 150000);
// A whale object is created
Aquatic shark = new Aquatic(400, 2150);
// A shark object is created
Animal q [] = {
whale, shark };
// Array of aquatic animals
AnimalWorld<Aquatic> qList = new AnimalWorld<Aquatic>(q);
// Place the aquatics into a list
// Create a list of land animals
Land owl = new Land(3, 1, 0);
// A land owl object is created
Land l [] = { owl };
// An
array of land objects is created
AnimalWorld<Land> lList = new AnimalWorld<Land>(l);
// Place the animals into a list
// Create a list of pet animals
Pet dog = new Pet(15, 75, 2, “Prince”);
// A pet dog object is created
Pet p [] = { new Pet(15, 75, 2, “Prince”) };
// An array of pet objects is
created
AnimalWorld<Pet> pList = new AnimalWorld<Pet>(p);
// Place the pets into a list
// Create a list of wild animals
Wild cheetah = new Land(15, 75, 2);
// A cheetah object is created
Wild deer = new Land(10, 50, 1);
// A deer object is created
Wild w [] = { cheetah, deer };
// Array of non-aquatic animals
AnimalWorld<Wild> wList = new AnimalWorld<Wild>(w);
// Place the wilds into a list
// Call the methods and see the
outcomes
// vitality(…) is with unlimited wildcard argument and
// hence we can pass argument of any type
vitality (uList); // OK
vitality (qList); // OK
vitality (lList);
// OK
vitality (pList);
// OK
vitality (wList);
// OK
// showSea(…) is with lower bound
wildcard argument with
// class Aquatic and its super classes
showSea (uList); // OK
showSea (qList); // OK
showSea (lList);
// Compile-time error
showSea (pList);
//
Compile-time error
showSea (wList);
//
Compile-time error
// showLand(…) is with upper bound
wildcard argument with
// class Land and its subclasses
showLand (uList); // Compile-time error
showLand (qList); // Compile-time error
showLand (lList);
// OK
showLand (pList);
// OK
showLand (wList);
// OK
// showPet(…) is with upper bound
wildcard argument with
// class Pet and its subclasses
showPet (uList); // Compile-time error
showPet (qList); // Compile-time error
showPet (lList); // Compile-time error
showPet (pList);
// OK
showPet (wList);
//
Compile-time error
// showWild(…) is with upper bound
wildcard argument with
// class Wild and its sub classes
showWild (uList); // Compile-time error
showWild (qList); // Compile-time error
showWild (lList);
//
Compile-time error
showWild (pList);
//
Compile-time error
showWild (wList);
// OK
}
}